    #include <bits/stdc++.h>
/*
// 将所有存在交集的区间合并
void merge(vector<PII> &segs) //将seg里面的各个区间都合并了
{
    vector<PII> res;

    sort(segs.begin(), segs.end());

    int st = -2e9, ed = -2e9; //头指针思想 同步操作
    for (auto seg : segs)
        if (ed < seg.first)
        {
            if (st != -2e9) res.push_back({st, ed});
            st = seg.first, ed = seg.second;
        }
        else ed = max(ed, seg.second);

    if (st != -2e9) res.push_back({st, ed});

    segs = res;
}

*/
    using namespace std;
    /*
    这里是正确的思路:
    1. 先排序 这样一来，前面的肯定是begin更小的
    所以 只要看end就好了，极大得减轻了工作量
    2.如果当前的end 在后一个的范围内(>begin`)
    那么直接扩容
    否则不能合并，就push当前的这一个区间
    3.最后，剩下一个区间没有合并，把最后一个区间加入进去即可
    */
    struct Interval{
        int begin;
        int end;

        Interval(int b,int e){
            this->begin = b;
            this->end = e;
        }
    };
    bool cmp(Interval &a, Interval &b){ 
            return a.begin < b.begin; //begin小的在前
    };
    int n;
    vector<Interval> mp,res;
    int main()
    {
        cin>>n;
        for(int i=0;i<n;i++){
            int begin,end;cin>>begin>>end;
            Interval temp(begin,end);
            mp.push_back(temp);
        }

        sort(mp.begin(),mp.end(),cmp);
    

        int curBegin = -1e9-2,curEnd = -1e9-2; //用于同步操作，类似链表的头节点
        for(int i=0;i<n;i++){
            if (curEnd<mp[i].begin){ //不能合并
                if (curEnd!=-1e9-2){
                    //如果不能合并，那就push进去前一个
                    Interval temp(curBegin,curEnd);
                    res.push_back(temp);
                }
                curBegin = mp[i].begin;
                curEnd = mp[i].end;
            }else if (curEnd<mp[i].end){ //这里不能是else，必须是else if 交集的情况  如果是else，那么子集的情况会把end 的范围改小
                //交集的能合并（最普通的情况）
                curEnd = mp[i].end;
            }//因为排序后,（1,10） （5,6） 这种不需要修改curEnd所以不用考虑
        }


        Interval final(curBegin,curEnd);
        res.push_back(final);

        cout<<res.size();
        return 0;
    }
